"use strict";

module.exports = core;
const path = require("path");
const colors = require("colors");
const semver = require("semver");
const userHome = require("user-home");
const pathExists = require("path-exists").sync;
const cmmander = require("commander");
const init = require("@zhuj-cli-dev/init");
const exec = require("@zhuj-cli-dev/exec");
// checkInputArgs();
const log = require("@zhuj-cli-dev/log");

const constanst = require("./const");
const pkg = require("../package.json");

let args;
const { Command } = cmmander;
let program = new Command();
// 入口
async function core() {
  try {
    await prepare();
    registerCommand();
  } catch (error) {
    console.log("🚀 ~ core ~ error:", error)
  }
}
async function prepare() {
  checkPkgVersion();
  checkRoot();
  checkUserHome();
  // checkInputArgs();
  checkEnv();
  await checkGlobalUpdate();
}

function checkPkgVersion() {
  // console.log(pkg.version)
  log.notice("cli", pkg.version);
}

// 检测root账号
function checkRoot() {
  // 暂时不支持 ES6 的写法
  const rootCheck = require("root-check"); // root-check 检测是否是root账号
  rootCheck();
  // console.log("checkRoot", process.geteuid);
}

// 检测用户
function checkUserHome() {
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red(`当前用户目录不存在，请检查用户目录是否正确!`));
  }
}

// 检测入参
function checkInputArgs() {
  // minimist 库，参数解析
  const minimist = require("minimist");
  args = minimist(process.argv.slice(2));
  checkArgs();
}

function checkArgs() {
  if (args.debug) {
    process.env.LOG_LEVEL = "verbose";
  } else {
    process.env.LOG_LEVEL = "info";
  }
  log.level = process.env.LOG_LEVEL;
}
// 加载环境变量 dotenv
function checkEnv() {
  const dotenv = require("dotenv");
  const dotenvPath = path.resolve(userHome, ".env");
  console.log("🚀 ~ checkEnv ~ userHome:", userHome)
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: dotenvPath,
    });
  }
  createDefaultConfig();
  log.verbose("环境变量 config", process.env.CLI_HOME_PATH);
}

function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig["cliHome"] = path.join(userHome, constanst.DEFAULT_CLI_HOME);
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome;
  return cliConfig;
}

// 全局检测版本是否最新
async function checkGlobalUpdate() {
  // 1、获取当前版本号和模块名
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  // 2、调用npm API，获取所有版本号
  const { getNpmSemverVersions } = require("@zhuj-cli-dev/get-npm-info");
  const lastVersion = await getNpmSemverVersions(currentVersion, npmName);
  log.verbose("data", lastVersion);
  // 3、比对版本号
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    // 4、获取最新版本号，提示用户更新到该版本
    log.warn(
      colors.yellow(
        `请手动更新 ${npmName}，当前版本：${currentVersion}，最新版本：${lastVersion}
              更新命令： npm install -g ${npmName}
        `
      )
    );
  }
}

// 命令注册
function registerCommand() {
  const name = Object.keys(pkg.bin);
  // 初始化
  program
    .name(name[0])
    .usage("<command> [options]")
    .version(pkg.version)
    .option("-d, --debug", "是否开启调试模式", false)
    .option("-tp, --targetPath <targetPath>", "是否指定本地调试路径", "");

  program
    .command("init [projectName]")
    .option("-f, --force", "是否强制初始化项目")
    .action(exec);

  // 监听debug模式
  program.on("option:debug", function () {
    if (program.debug) {
      process.env.LOG_LEVEL = "verbose";
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
  });

  // 监听  targetPath 命令
  program.on("option:targetPath", function () {
    process.env.CLI_TARGET_PATH = program.targetPath;
  });

  // 监听未注册命令
  program.on("command:*", function (obj) {
    const availableCommands = program.commands.map((cmd) => cmd.name());
    console.log(colors.red("未知的命令：", obj[0]));
    if (availableCommands.length) {
      console.log(colors.red("可用的命令：", availableCommands.join(",")));
    }
  });

  program.parse(process.argv);
  // 帮助文档
  if (program.args && program.args.length < 1) {
    program.outputHelp();
  }
}
